#include"SatelliteMGR.hpp"
#include"MapApp.hpp"
#include"../Base/Concurrency/Lock.hpp"
#include<filesystem>
#include<fstream>
#include"rapidjson/document.h"

namespace SC_SUN
{

int SatelliteMGR::LoadData()
{
    using namespace rapidjson;

    mAllPrtDvaMat.clear();
    mSatellites.clear();
    mSatelliteSNs.clear();

    int num = 0;

    //读取配置文件目录
    std::string path = mApp.CurScene() + "/Data_Summary/Sat_Info.json";

    //读取字符串数据
    int fileLen = std::filesystem::file_size(path);
    std::string data;
    data.resize(fileLen);
    FILE* pf = fopen(path.data(), "rb");
    fread(data.data(), 1, fileLen, pf);
    fclose(pf);

    //解析json数据
    Document doc;
    doc.Parse(data.data());
    auto array = doc.GetArray();

    //加载10020颗卫星的数据
    for (int i = 0; i < array.Size(); i++)
    {
        //获取json对象
        auto object = array[i].GetObj();
        EvSatelliteData sat;
        
        //解析数据
        sat.SAT_SN = object["SAT_SN"].GetString();
        sat.SAT_ID = object["SAT_ID"].GetString();
        sat.SAT_STP = object["SAT_STP"].GetDouble();
        sat.SAT_SQ = object["SAT_SQ"].GetDouble();
        sat.PATH_SAT_SN = object["sat_path"].GetString();
        sat.PATH_SAT_SI = object["SAT_SI"].GetString();
        sat.PATH_SAT_CL = object["SAT_CL"].GetString();
        sat.PATH_SAT_ORB = object["SAT_ORB"].GetString();

        //由于路径问题需要去掉一部分
        std::string path = mApp.CurScene();
        int idx = path.find_last_of('/');
        path = path.substr(0, idx + 1);

        //读取SI数据
        std::string PATH_SAT_SI = path + sat.PATH_SAT_SI;
        Document doc2;
        fileLen = std::filesystem::file_size(PATH_SAT_SI);
        std::string buff;
        buff.resize(fileLen);
        pf = fopen(PATH_SAT_SI.data(), "rb");
        fread(buff.data(), 1, fileLen, pf);
        fclose(pf);
        doc2.Parse(buff.data());
        auto object2 = doc2.GetObj();
        sat.SAT_SI.SAT_SN = object2["SAT_SN"].GetString();
        sat.SAT_SI.mStartTime.JD = object2["JD_MS"].GetDouble();
        sat.SAT_SI.mStartTime.YY = object2["UTC_start"].GetArray()[0].GetUint();
        sat.SAT_SI.mStartTime.MM = object2["UTC_start"].GetArray()[1].GetUint();
        sat.SAT_SI.mStartTime.DD = object2["UTC_start"].GetArray()[2].GetUint();
        sat.SAT_SI.mStartTime.HH = object2["UTC_start"].GetArray()[3].GetUint();
        sat.SAT_SI.mStartTime.MI = object2["UTC_start"].GetArray()[4].GetUint();
        sat.SAT_SI.mStartTime.SS = object2["UTC_start"].GetArray()[5].GetDouble();
        sat.SAT_SI.SAT_ATN[0] = object2["SAT_ATN"].GetArray()[0].GetDouble();
        sat.SAT_SI.SAT_ATN[1] = object2["SAT_ATN"].GetArray()[1].GetDouble();
        sat.SAT_SI.SAT_ATN[2] = object2["SAT_ATN"].GetArray()[2].GetDouble();
        sat.SAT_SI.CST_MASS = object2["CST_MASS"].GetDouble();
        sat.SAT_SI.CST_AAD = object2["CST_AAD"].GetDouble();
        sat.SAT_SI.CST_ASR = object2["CST_ASR"].GetDouble();
        sat.SAT_SI.SAT_ATN_DR = object2["SAT_ATN_DR"].GetDouble();
        sat.SAT_SI.SAT_ATN_DA = object2["SAT_ATN_DA"].GetDouble();
        sat.SAT_SI.SAT_SQ = object2["SAT_SQ"].GetDouble();
        sat.SAT_SI.SAT_SQ_ER = object2["SAT_SQ_ER"].GetDouble();
        sat.SAT_SI.SAT_SQ_DR = object2["SAT_SQ_DR"].GetDouble();
        sat.SAT_SI.SAT_HD = object2["SAT_HD"].GetDouble();
        
        //读取CL数据
        std::string PATH_SAT_CL = path + sat.PATH_SAT_CL;
        Document doc3;
        fileLen = std::filesystem::file_size(PATH_SAT_CL);
        buff.resize(fileLen);
        pf = fopen(PATH_SAT_CL.data(), "rb");
        fread(buff.data(), 1, fileLen, pf);
        fclose(pf);
        doc3.Parse(buff.data());
        auto object3 = doc3.GetObj();
        sat.SAT_CL.SAT_SN = object3["SAT_SN"].GetString();
        for (int i = 0; i < object3["SAT_JD_HF"].GetArray().Size(); i++)
        {
            sat.SAT_CL.SAT_JD_HF.push_back(object3["SAT_JD_HF"].GetArray()[i].GetDouble());
        }
        for (int i = 0; i < object3["SAT_ST_HF"].GetArray().Size(); i++)
        {
            sat.SAT_CL.SAT_ST_HF.push_back(object3["SAT_ST_HF"].GetArray()[i].GetDouble());
        }
        for (int i = 0; i < object3["SAT_JD_MS"].GetArray().Size(); i++)
        {
            sat.SAT_CL.SAT_JD_MS.push_back(object3["SAT_JD_MS"].GetArray()[i].GetDouble());
        }
        for (int i = 0; i < object3["SAT_ST_MS"].GetArray().Size(); i++)
        {
            sat.SAT_CL.SAT_ST_MS.push_back(object3["SAT_ST_MS"].GetArray()[i].GetDouble());
        }
        for (int i = 0; i < object3["SAT_ST_ER"].GetArray().Size(); i++)
        {
            sat.SAT_CL.SAT_ST_ER.push_back(object3["SAT_ST_ER"].GetArray()[i].GetDouble());
        }
        //sat.SAT_CL.SAT_ER_DR = object3["SAT_ER_DR"].GetDouble();
        for (int i = 0; i < object3["SAT_ER_DR"].GetArray().Size(); i++)
        {
            sat.SAT_CL.SAT_ER_DR.push_back(object3["SAT_ER_DR"].GetArray()[i].GetDouble());
        }

        //读取ORB数据
        std::string PATH_SAT_ORB = path + sat.PATH_SAT_ORB;
        Document doc4;
        fileLen = std::filesystem::file_size(PATH_SAT_ORB);
        buff.resize(fileLen);
        pf = fopen(PATH_SAT_ORB.data(), "rb");
        fread(buff.data(), 1, fileLen, pf);
        fclose(pf);
        doc4.Parse(buff.data());
        auto object4 = doc4.GetObj();
        sat.SAT_ORB.SAT_SN = object4["SAT_SN"].GetString();
        for (int i = 0; i < object4["SAT_ST_HF"].GetArray().Size(); i++)
        {
            sat.SAT_ORB.SAT_ST_HF.push_back(object4["SAT_ST_HF"].GetArray()[i].GetDouble());
        }
        for (int i = 0; i < object4["SAT_POS_HF"].GetArray().Size(); i++)
        {
            sat.SAT_ORB.SAT_POS_HF.push_back(object4["SAT_POS_HF"].GetArray()[i][0].GetDouble());
            sat.SAT_ORB.SAT_POS_HF.push_back(object4["SAT_POS_HF"].GetArray()[i][1].GetDouble());
            sat.SAT_ORB.SAT_POS_HF.push_back(object4["SAT_POS_HF"].GetArray()[i][2].GetDouble());
        }
        for (int i = 0; i < object4["SAT_VEL_HF"].GetArray().Size(); i++)
        {
            sat.SAT_ORB.SAT_VEL_HF.push_back(object4["SAT_VEL_HF"].GetArray()[i][0].GetDouble());
            sat.SAT_ORB.SAT_VEL_HF.push_back(object4["SAT_VEL_HF"].GetArray()[i][1].GetDouble());
            sat.SAT_ORB.SAT_VEL_HF.push_back(object4["SAT_VEL_HF"].GetArray()[i][2].GetDouble());
        }
        for (int i = 0; i < object4["SAT_POS_MS"].GetArray().Size(); i++)
        {
            sat.SAT_ORB.SAT_POS_MS.push_back(object4["SAT_POS_MS"].GetArray()[i][0].GetDouble());
            sat.SAT_ORB.SAT_POS_MS.push_back(object4["SAT_POS_MS"].GetArray()[i][1].GetDouble());
            sat.SAT_ORB.SAT_POS_MS.push_back(object4["SAT_POS_MS"].GetArray()[i][2].GetDouble());
        }
        for (int i = 0; i < object4["SAT_VEL_MS"].GetArray().Size(); i++)
        {
            sat.SAT_ORB.SAT_VEL_MS.push_back(object4["SAT_VEL_MS"].GetArray()[i][0].GetDouble());
            sat.SAT_ORB.SAT_VEL_MS.push_back(object4["SAT_VEL_MS"].GetArray()[i][1].GetDouble());
            sat.SAT_ORB.SAT_VEL_MS.push_back(object4["SAT_VEL_MS"].GetArray()[i][2].GetDouble());
        }
        for (int i = 0; i < object4["SAT_POS_ER"].GetArray().Size(); i++)
        {
            sat.SAT_ORB.SAT_POS_ER.push_back(object4["SAT_POS_ER"].GetArray()[i][0].GetDouble());
            sat.SAT_ORB.SAT_POS_ER.push_back(object4["SAT_POS_ER"].GetArray()[i][1].GetDouble());
            sat.SAT_ORB.SAT_POS_ER.push_back(object4["SAT_POS_ER"].GetArray()[i][2].GetDouble());
        }
        for (int i = 0; i < object4["SAT_VEL_ER"].GetArray().Size(); i++)
        {
            sat.SAT_ORB.SAT_VEL_ER.push_back(object4["SAT_VEL_ER"].GetArray()[i][0].GetDouble());
            sat.SAT_ORB.SAT_VEL_ER.push_back(object4["SAT_VEL_ER"].GetArray()[i][1].GetDouble());
            sat.SAT_ORB.SAT_VEL_ER.push_back(object4["SAT_VEL_ER"].GetArray()[i][2].GetDouble());
        }
        for (int i = 0; i < object4["SUN_POS"].GetArray().Size(); i++)
        {
            sat.SAT_ORB.SUN_POS.push_back(object4["SUN_POS"].GetArray()[i][0].GetDouble());
            sat.SAT_ORB.SUN_POS.push_back(object4["SUN_POS"].GetArray()[i][1].GetDouble());
            sat.SAT_ORB.SUN_POS.push_back(object4["SUN_POS"].GetArray()[i][2].GetDouble());
        }
        for (int i = 0; i < object4["LNR_POS"].GetArray().Size(); i++)
        {
            sat.SAT_ORB.LNR_POS.push_back(object4["LNR_POS"].GetArray()[i][0].GetDouble());
            sat.SAT_ORB.LNR_POS.push_back(object4["LNR_POS"].GetArray()[i][1].GetDouble());
            sat.SAT_ORB.LNR_POS.push_back(object4["LNR_POS"].GetArray()[i][2].GetDouble());
        }
        for (int i = 0; i < object4["EAR_NUT"].GetArray().Size(); i++)
        {
            sat.SAT_ORB.EAR_NUT.push_back(object4["EAR_NUT"].GetArray()[i][0].GetDouble());
            sat.SAT_ORB.EAR_NUT.push_back(object4["EAR_NUT"].GetArray()[i][1].GetDouble());
            sat.SAT_ORB.EAR_NUT.push_back(object4["EAR_NUT"].GetArray()[i][2].GetDouble());
        }
        for (int i = 0; i < object4["EAR_PRE"].GetArray().Size(); i++)
        {
            sat.SAT_ORB.EAR_PRE.push_back(object4["EAR_PRE"].GetArray()[i][0].GetDouble());
            sat.SAT_ORB.EAR_PRE.push_back(object4["EAR_PRE"].GetArray()[i][1].GetDouble());
            sat.SAT_ORB.EAR_PRE.push_back(object4["EAR_PRE"].GetArray()[i][2].GetDouble());
        }
        for (int i = 0; i < object4["EAR_ROT"].GetArray().Size(); i++)
        {
            sat.SAT_ORB.EAR_ROT.push_back(object4["EAR_ROT"].GetArray()[i].GetDouble());
        }
        for (int i = 0; i < object4["HDF_ER"].GetArray().Size(); i++)
        {
            sat.SAT_ORB.HDF_ER.push_back(object4["HDF_ER"].GetArray()[i][0].GetDouble());
            sat.SAT_ORB.HDF_ER.push_back(object4["HDF_ER"].GetArray()[i][1].GetDouble());
            sat.SAT_ORB.HDF_ER.push_back(object4["HDF_ER"].GetArray()[i][2].GetDouble());
        }

        ///由于数据数据是一起给过来来的得先缓存起来再拆开
        auto object5 = object4["PrtDvaMat"].GetArray();
        std::vector<std::vector<std::vector<double>>> allPrtDvaMat(object5.Size());
        for (int i = 0; i < object5.Size(); i++)
        {
            auto object6 = object5[i].GetArray();
            std::vector<std::vector<double>> data6(object6.Size());
            for (int j = 0; j < object6.Size(); j++)
            {
                auto object7 = object6[j].GetArray();
                std::vector<double> data7(object7.Size());
                for (int z = 0; z < object7.Size(); z++)
                {
                    data7[z] = object7[z].GetDouble();
                }
                data6[j] = data7;
            }
            allPrtDvaMat[i] = data6;
        }
        //插入所有数据
        mMutex.Lock();
        mAllPrtDvaMat.insert({sat.SAT_SN, allPrtDvaMat});
        mSatelliteSNs.push_back(sat.SAT_SN);
        mMutex.Unlock();

        //获取第1帧的数据
        sat.SAT_ORB.PrtDvaMat.resize(6 * 6);
        for (int i = 0; i < 6; i++)
        {
            for (int j = 0; j < 6; j++)
            {
                sat.SAT_ORB.PrtDvaMat[i * 6 + j] = allPrtDvaMat[i][j][0];
            }
        }

        //添加实体变量
        AddSatellite(sat.SAT_SN, sat);

        num++;
    }

    return num;
}


bool SatelliteMGR::AddSatellite(const std::string& SatSN, const EvSatelliteData& sat)
{

    MMF::LockGuard lk(mMutex);

    //不存在就开始添加
    if (mSatellites.find(SatSN) == mSatellites.end())
    {
        mSatellites.insert({SatSN, sat});
        return true;
    }

    return false;
}


bool SatelliteMGR::FindSatellite(const std::string& SatSN)
{
    MMF::LockGuard lk(mMutex);
    return mSatellites.find(SatSN) != mSatellites.end();
}


EvSatelliteData* SatelliteMGR::GetSatellite(const std::string& SatSN, uint32_t sliceIdx)
{
    MMF::LockGuard lk(mMutex);

    //存在就开始获取
    std::unordered_map<std::string, EvSatelliteData>::iterator it = mSatellites.find(SatSN);
    if (it != mSatellites.end())
    {
        ///还需要根据具体的切片规则，获取转移矩阵的6 * 6数据
        std::unordered_map<std::string, std::vector<std::vector<std::vector<double>>>>::iterator it2 = mAllPrtDvaMat.find(SatSN);
        std::vector<std::vector<std::vector<double>>>& allPrtDvaMat = it2->second;
        if (allPrtDvaMat[0][0].size() <= sliceIdx)
            return nullptr;

        for (int i = 0; i < 6; i++)
        {
            for (int j = 0; j < 6; j++)
            {
                it->second.SAT_ORB.PrtDvaMat[i * 6 + j] = allPrtDvaMat[i][j][sliceIdx];
            }
        }

        return &(it->second);
    }
    return nullptr;
}


bool SatelliteMGR::DeleteSatellite(const std::string& SatSN)
{
    MMF::LockGuard lk(mMutex);

    //存在就开始删除
    std::unordered_map<std::string, EvSatelliteData>::iterator it = mSatellites.find(SatSN);
    if (it != mSatellites.end())
    {
        mSatellites.erase(it);
        return true;
    }
    return false;
}


bool SatelliteMGR::AddParent(const std::string& SatSN, const std::string& ParentSatSN)
{
    MMF::LockGuard lk(mMutex);

    //不存在就开始添加
    std::unordered_map<std::string, EvSatelliteData>::iterator it = mSatellites.find(SatSN);
    if (it != mSatellites.end())
    {
        for (int i = 0; i < it->second.Parents.size(); i++)
        {
            if (it->second.Parents[i] == ParentSatSN)
                return false;
        }

        it->second.Parents.push_back(ParentSatSN);
        return true;
    }
    return false;
}


bool SatelliteMGR::DeleteParent(const std::string& SatSN, const std::string& ParentSatSN)
{
    MMF::LockGuard lk(mMutex);

    //不存在就开始添加
    std::unordered_map<std::string, EvSatelliteData>::iterator it = mSatellites.find(SatSN);
    if (it != mSatellites.end())
    {
        int idx = -1;
        for (int i = 0; i < it->second.Parents.size(); i++)
        {
            if (it->second.Parents[i] == ParentSatSN)
            {
                idx = i;
                break;
            }
        }

        if (idx >= 0)
            it->second.Parents.erase(it->second.Parents.begin() + idx);
        else 
            return false;

        return true;
    }
    return false;
}


bool SatelliteMGR::AddChild(const std::string& SatSN, const std::string& ChildSatSN)
{
    MMF::LockGuard lk(mMutex);

    //不存在就开始添加
    std::unordered_map<std::string, EvSatelliteData>::iterator it = mSatellites.find(SatSN);
    if (it != mSatellites.end())
    {
        for (int i = 0; i < it->second.Children.size(); i++)
        {
            if (it->second.Children[i] == ChildSatSN)
                return false;
        }

        it->second.Children.push_back(ChildSatSN);
        return true;
    }
    return false;
}



bool SatelliteMGR::DeleteChild(const std::string& SatSN, const std::string& ChildSatSN)
{
    MMF::LockGuard lk(mMutex);

    //不存在就开始添加
    std::unordered_map<std::string, EvSatelliteData>::iterator it = mSatellites.find(SatSN);
    if (it != mSatellites.end())
    {
        int idx = -1;
        for (int i = 0; i < it->second.Children.size(); i++)
        {
            if (it->second.Children[i] == ChildSatSN)
            {
                idx = i;
                break;
            }
        }

        if (idx >= 0)
            it->second.Children.erase(it->second.Children.begin() + idx);
        else 
            return false;

        return true;
    }
    return false;
}



bool SatelliteMGR::ClearAllCollections()
{
    MMF::LockGuard lk(mMutex);

    for (auto [_, sat]: mSatellites)
    {
        sat.Parents.clear();
        sat.Children.clear();
    }

    return true;
}


const std::vector<std::string>& SatelliteMGR::GetSatelliteList()
{
    return mSatelliteSNs;
}


void SatelliteMGR::GetTimeAndStep(double& time, double& step)
{
    time = mSatellites.begin()->second.SAT_STP;
    step = -1.0;
}

}
